package com.unitd.base.module.master.service.impl;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.unitd.base.frame.enums.ResultEnum;
import com.unitd.base.frame.exception.UnitdException;
import com.unitd.base.frame.plugin.aliyun.AliyunSmsConfiguration;
import com.unitd.base.frame.util.BeanUtils;
import com.unitd.base.frame.util.DateUtils;
import com.unitd.base.frame.util.StringUtils;
import com.unitd.base.module.comm.utils.Constant;
import com.unitd.base.module.master.mybatis.mapper.SmsLogMapper;
import com.unitd.base.module.master.pojo.po.SmsLogPO;
import com.unitd.base.module.master.service.SmsLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * 应用日志信息处理的业务逻辑实现类
 *
 * @author SmsLog
 * @version 1.0
 * @filename SmsLogServiceImpl.java
 * @copyright www.pactera.com
 * @date 2020-08-28
 */
@Slf4j
@Service
public class SmsLogServiceImpl extends ServiceImpl<SmsLogMapper, SmsLogPO> implements SmsLogService {

    /** 当日最大发送次数 */
    @Value("${unitd.sms.maxRegisterNum}")
    private int maxRegisterNum;
    @Autowired
    AliyunSmsConfiguration aliyunSmsConfiguration;
    @Autowired
    private SmsLogMapper smsLogMapper;

    /**
     * 发送手机验证码
     *
     * @param mobile 接收验证码的手机号码
     * @return 验证码
     */
    @Override
    @Transactional
    public String sendVerifyCode(String mobile) {
        log.info("发送短信手机号:[{}]", mobile);

        // 检测手机号是否合法
        if (!StringUtils.isChinaPhoneLegal(mobile)) {
            throw new UnitdException(ResultEnum.MOBILE_NUM_ERROR);
        }

        // 先判断是否存在今日的短信发送记录
        String currDay = DateUtils.format(new Date(), DateUtils.DAY_STR);
        SmsLogPO oldSendRecord = this.getOldSendRecord(mobile);

        // 获取4位随机短信验证码
        String verifyNo = StringUtils.createSmsVerifyNo();

        if (!BeanUtils.isNull(oldSendRecord)) {
            Integer regisNumData = oldSendRecord.getSendNum();
            if (regisNumData >= maxRegisterNum) {
                // 未注册，每日注册短信只能发送5条
                throw new UnitdException(ResultEnum.SMS_DAY_LIMIT_ERROR);
            }

            Date updateTime = oldSendRecord.getUpdateTime();
            if (BeanUtils.isNull(updateTime)) {
                updateTime = DateUtils.getCurrDate();
            }
            // 失效时间
            Date effectDate = DateUtils.calculateDate(updateTime, 60);
            int n = DateUtils.compareDate(effectDate, new Date());
            if (n == -1) {
                // 一分钟之内只能发送一次
                throw new UnitdException(ResultEnum.SMS_MINUTE_ONCE_ERROR);
            }

            // 修改
            oldSendRecord.setSmsCode(verifyNo);
            oldSendRecord.setSendNum(oldSendRecord.getSendNum() + 1);
            oldSendRecord.setSuccessNum(oldSendRecord.getSuccessNum() + 1);
            oldSendRecord.setUpdateTime(updateTime);

            smsLogMapper.updateById(oldSendRecord);
        } else {
            oldSendRecord = new SmsLogPO();

            //新增，插入一条短信发送记录
            oldSendRecord.setSmsCode(verifyNo);
            oldSendRecord.setPhone(mobile);
            oldSendRecord.setSendDay(currDay);
            oldSendRecord.setSendNum(1);
            oldSendRecord.setSuccessNum(1);
            oldSendRecord.setErrorNum(0);

            //生效状态
            oldSendRecord.setStatus("1");
            //是否已删除
            oldSendRecord.setDeleteFlag("0");
            //创建时间
            oldSendRecord.setCreateTime(DateUtils.getCurrDate(DateUtils.TIMESTAMP_PATTERN));
            //更新时间
            oldSendRecord.setUpdateTime(DateUtils.getCurrDate(DateUtils.TIMESTAMP_PATTERN));

            smsLogMapper.insert(oldSendRecord);
        }

        // 调用短信渠道接口发送短信
        SendSmsResponse response = aliyunSmsConfiguration.sendSms(mobile, verifyNo);
        if (!BeanUtils.isNull(response) && Constant.ALIYUN_SMS_RSP_SUCCESS_CODE.equals(response.getCode())) {
            log.info("短信发送成功!");
            return verifyNo;
        } else {
            log.info("短信发送失败![{}]", response.getMessage());
            throw new UnitdException(ResultEnum.SMS_SEND_ERROR);
        }
    }

    /**
     * 获取指定手机号当日的最新验证码信息
     *
     * @param mobile 指定手机号
     * @return 验证码信息
     */
    @Override
    public SmsLogPO getOldSendRecord(String mobile) {
        // 先判断是否存在今日的短信发送记录
        String currDay = DateUtils.format(new Date(), DateUtils.DAY_STR);
        SmsLogPO oldSendRecord = smsLogMapper.selectByMobileNoAndSendDay(mobile, currDay);
        log.info("当日短信发送记录:[{}]", oldSendRecord);
        return oldSendRecord;
    }
}
